/**
 * Copyright (c) 2012, Gelssoft Co.,Ltd. All Right reserved.
 * GELSSOFT PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.web.server.common.dao;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.type.Type;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

/**
 * 本类是系统数据库操作接口FiaDao的实现类。
 * 
 * 该类实现了数据库的基本添加、删除、修改、查询操作。<br>
 * 系统采用了Spring提供的声明式事务，HibernateTemplate，所以在对数据库进行操作的时候不需要显示的去连接关闭数据库和提交事务。<br>
 * 该接口只是提供了基本的数据库操作，如果存在复杂的操作可以在其子类中对其扩展。<br>
 *
 * @author 刘宗威
 * @version 0.1 2011-4-26
 * @since FIA 2.0
 */
@SuppressWarnings("unchecked")
public class GelsDaoImpl extends HibernateDaoSupport implements GelsDao {

    /**
     * JDBC数据库操作对象
     */
    protected NamedParameterJdbcTemplate jdbcTemplate = null;
    
    /**
     * 默认构造方法
     * 
     */     
    public GelsDaoImpl(){
        
    }

    /**
     * 添加、修改实体对象
     * 
     * @param   entity 需要添加或者修改的对象
     */
    public void addOrUpdateObject(Object entity) {
    	getHibernateTemplate().saveOrUpdate(entity);
    }
    
    /**
     * 返回当前hibernate的session。
     * @return
     */
    public Session getCurrenSession() {
    	return this.getSession();
    }

    /**
     * 删除实体对象
     * 
     * @param   entityClass 需要删除的实体类。
     * @param   id    需要删除的实体对象的主键。
     */
    public void deleteObject(Class entityClass, Serializable id) {
        getHibernateTemplate().delete(getObject(entityClass, id));
    }

    /**
     * 批量删除、修改实体对象
     * 
     * @param   hql 需要执行的批处理语句
     * @return  int 操作影响到的记录行数。
     */
    public int bulkByNamedParam(final String hql) {
        Integer bulkCount = (Integer) (getHibernateTemplate()
                .execute(new HibernateCallback() {
                    public Object doInHibernate(Session session) {
                        // 执行批量修改、删除并获得成功的记录个数
                        int count = session.createQuery(hql).executeUpdate();
                        return count;
                    }
                }));
        return bulkCount.intValue();
    }

    /**
     * 查询单个实体对象。
     * 
     * @param   clazz  需要查询的实体类。
     * @param   id     需要查询的实体对象的主键。
     * @return  Object 查询出来的实体对象，对象可能为null。
     */
    public <T> T getObject(Class<T> clazz, Serializable id) {
        return (T) getHibernateTemplate().get(clazz, id);
    }

    /**
     * 查询全部实体对象
     * 
     * @param   clazz 需要查询的实体类。
     * @return  List  查询出来的实体对象集合。
     */
    public List loadObjects(Class clazz) {
        return getHibernateTemplate().loadAll(clazz);
    }

    /**
     * 查询实体对象组合结果集。
     * 
     * @param   hql  需要执行的hql语句。
     * @return  List 查询出来的实体对象组合结果集。
     */
    public List queryByHql(final String hql) {
        return getHibernateTemplate().find(hql);
    }
    
    /**
     * 根据查询语句查询单个对象
     * 
     * @param   hql  需要执行的hql语句。
     * @return  Object 查询出来的实体对象,对象可能为null。
     */
    public Object querySingleObjectByHql(final String hql) {
    	List list = queryByHql(hql);
    	
    	if (list.isEmpty()) {
    		return null;
    	} else {
    		return list.get(0);
    	}
    }
    
    /**
     * 查询指定范围内的实体对象组合结果集<br>
     * 
     * @param   hql       hql语句
     * @param   startData 起始
     * @param   length    结束
     * @return  List      查询出来的实体对象组合结果集。
     */
    public List queryByHql(final String hql,final int startData,final int length){
        
        return  getHibernateTemplate().executeFind( new  HibernateCallback() {   
            public  Object doInHibernate(Session session) throws  HibernateException, SQLException {   
                return  session.createQuery(hql).setFirstResult(startData).setMaxResults(length).list();   
            }   
        });          
    }
    
    /**
     * 查询指定范围内的实体对象组合结果集<br>
     * 
     * @param   sql       sql语句
     * @param   startData 起始
     * @param   length    结束
     * @param objs 参数值
     * @param types 参数值的类型
     * @return  List      查询出来的实体对象组合结果集。
     */
    public List queryBySql(final String sql, final int startData, final int length, final Object[] objs, final Type[] types){
        
        return  getHibernateTemplate().executeFind( new  HibernateCallback() {   
            public  Object doInHibernate(Session session) throws  HibernateException, SQLException {   
                return  session.createSQLQuery(sql).setParameters(objs, types).setFirstResult(startData).setMaxResults(length).list();   
            }   
        });          
    }
    
    /**
     * 参数查询
     * 
     * @param   hql         需要执行的hql语句。
     * @param   parammeters 参数集合
     * @return  List        查询出来的实体对象组合结果集对象，包含了分页信息。
     */
    public List queryByHqlParams(final String hql, Map<String, ? extends Object> parammeters) {
        
        // 定义参数名称、参数值对象
        Set<String> paramKeySet = parammeters.keySet();
        String[] paramNames = new String[paramKeySet.size()];
        Object[] paramValues = new Object[paramKeySet.size()];
        
        // 将参数集合拆分为参数名称数组、值数组，方便调用HibernateTemplate的参数查询方法
        Iterator<String> it = paramKeySet.iterator();
        int i = 0;
        String keyName;
        while(it.hasNext()){
            keyName = it.next();
            paramNames[i] = keyName;
            paramValues[i] = parammeters.get(keyName);
            i +=1;
        }       

        return getHibernateTemplate().findByNamedParam(hql, paramNames, paramValues);
    }
    
    /**
     * 使用JDBC的Sql语句进行数据库查询
     * 
     * @param   sql  需要执行的sql语句。
     * @return  List 查询出来的实体对象组合结果集对象。
     */ 
    public List queryByJdbc(String sql){
        return jdbcTemplate.getJdbcOperations().queryForList(sql);
    }
    
    /**
     * 使用JDBC的Sql语句进行数据库查询
     * 
     * @param   sql      需要执行的sql语句。
     * @param   paramMap 需要的参数以及值
     * @return  List     查询出来的实体对象组合结果集对象。
     */
    public List queryByJdbcParams(String sql, Map paramMap) {
        return jdbcTemplate.queryForList(sql, paramMap);
    }   
    
    public void setJdbcTemplate(NamedParameterJdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
    
    public int execute(String sql, Map paramMap) {
	    return this.jdbcTemplate.update(sql, paramMap);
	}

	/**
	 * 返回JdbcTemplate实例
	 */
	public NamedParameterJdbcTemplate getJdbcTemplate() {
		return this.jdbcTemplate;
	}
}
